// MyTime.cpp:
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyTime.h"

CMyTime::CMyTime()
{
	wYear=0;
	wMonth=0;
	wDay=0;
	wDayOfWeek=0;
	wHour=0;
	wMinute=0;
	wSecond=0;
	wMilliseconds=0;
}

CMyTime::CMyTime(CMyTime &mt)
{
	*this=mt;
}

CMyTime::CMyTime(DATE &date)
{
	VariantTimeToSystemTime(date,this);
}

void CMyTime::SetTime(WORD Year, WORD Month, WORD Day, WORD Hour, WORD Minute, WORD Second, WORD Millisecond)
{
	wYear=Year;
	wMonth=Month;
	wDay=Day;
	wDayOfWeek=0;
	wHour=Hour;
	wMinute=Minute;
	wSecond=Second;
	wMilliseconds=Millisecond;
}

void CMyTime::ClearTime()
{
	wYear=0;
	wMonth=0;
	wDay=0;
	wDayOfWeek=0;
	wHour=0;
	wMinute=0;
	wSecond=0;
	wMilliseconds=0;
}

void CMyTime::SetCurrentTime()
{
	FILETIME ft1;

	GetSystemTimeAsFileTime(&ft1);
	FileTimeToLocalFileTime(&ft1,&ft1);
	FileTimeToSystemTime(&ft1,this);
	
	//GetLocalTime(this);
}

CString CMyTime::GetLongTime()
{
	CString str;
	if(wYear!=0) str.Format("%04u.%02u.%02u %02u:%02u:%02u",wYear,wMonth,wDay,wHour,wMinute,wSecond);
	else str="-";
	return str;
}

CString CMyTime::GetShortTime()
{
	CString str;
	if(wYear!=0) str.Format("%02u:%02u:%02u",wHour,wMinute,wSecond);
	else str="-";
	return str;
}

CString CMyTime::GetShortTimeEx()
{
	CString str;
	if(wYear!=0) str.Format("%02u:%02u:%02u.%03u",wHour,wMinute,wSecond,wMilliseconds);
	else str="-";
	return str;
}

BOOL CMyTime::IsCorrect()
{
	if(wYear<1601 || wYear>30827 || wMonth<1 || wMonth>12 || \
	   wDay<1 || wDay>31 || wHour<0 || wHour>23 || wMinute<0 || wMinute>59 ||\
	   wSecond<0 || wSecond>59 || wMilliseconds<0 || wMilliseconds>999) return FALSE;
	else return TRUE;
}

BOOL CMyTime::IsNull()
{
	if(wYear==0) return TRUE;
	else return FALSE;
}

// returns difference between two dates as count of milliseconds
int CMyTime::operator-(const CMyTime &mt)
{
	FILETIME ft1,ft2;
	ULARGE_INTEGER ul1, ul2;

	if(mt.wYear==0) return MAX_LONG;

	SystemTimeToFileTime(this,&ft1);
	SystemTimeToFileTime(&mt,&ft2);

	ul1.HighPart = ft1.dwHighDateTime;
	ul1.LowPart = ft1.dwLowDateTime;
	ul2.HighPart = ft2.dwHighDateTime;
	ul2.LowPart = ft2.dwLowDateTime;

	return (int)((__int64)(ul1.QuadPart-ul2.QuadPart)/LEN_MS);
}

// returns difference between two dates as count of seconds
int CMyTime::GetDiffSec(CMyTime &mt)
{
	FILETIME ft1,ft2;
	ULARGE_INTEGER ul1, ul2;

	if(mt.wYear==0) return MAX_LONG;

	SystemTimeToFileTime(this,&ft1);
	SystemTimeToFileTime(&mt,&ft2);

	ul1.HighPart = ft1.dwHighDateTime;
	ul1.LowPart = ft1.dwLowDateTime;
	ul2.HighPart = ft2.dwHighDateTime;
	ul2.LowPart = ft2.dwLowDateTime;

	return (int)(((__int64)(ul1.QuadPart-ul2.QuadPart))/LEN_SEC);
}

void CMyTime::operator-=(const int shift_ms)
{
	FILETIME ft;
	ULARGE_INTEGER uli;
	
	SystemTimeToFileTime(this,&ft);
	uli.LowPart = ft.dwLowDateTime;
	uli.HighPart = ft.dwHighDateTime;
	
	uli.QuadPart-=shift_ms*LEN_MS;
	
	ft.dwLowDateTime = uli.LowPart;
	ft.dwHighDateTime = uli.HighPart;
	FileTimeToSystemTime(&ft, this);
}

void CMyTime::operator+=(const int shift_ms)
{
	FILETIME ft;
	ULARGE_INTEGER uli;
	
	SystemTimeToFileTime(this,&ft);
	uli.LowPart = ft.dwLowDateTime;
	uli.HighPart = ft.dwHighDateTime;
	
	uli.QuadPart+=shift_ms*LEN_MS;
	
	ft.dwLowDateTime = uli.LowPart;
	ft.dwHighDateTime = uli.HighPart;
	FileTimeToSystemTime(&ft, this);
}

CMyTime& CMyTime::operator=(const DATE &mt)
{
	VariantTimeToSystemTime(mt,this);
	
	return *this;
}

CMyTime& CMyTime::operator=(const time_t &mt)
{
	tm tmstruct;
	localtime_s(&tmstruct, &mt);

	wYear=tmstruct.tm_year+1900;
	wMonth=tmstruct.tm_mon+1;
	wDayOfWeek=tmstruct.tm_wday;
	wDay=tmstruct.tm_mday;
	wHour=tmstruct.tm_hour;
	wMinute=tmstruct.tm_min;
	wSecond=tmstruct.tm_sec;
	wMilliseconds=0;

	return *this;
}

CMyTime& CMyTime::operator=(const CTime &mt)
{
	mt.GetAsSystemTime(*this);
	
	return *this;
}

CMyTime& CMyTime::operator=(const ULONGLONG &mt)
{
	ULONGLONG rest=mt;

	wMilliseconds=(WORD)(rest%1000);
	rest/=1000;
	wSecond=(WORD)(rest%100);
	rest/=100;
	wMinute=(WORD)(rest%100);
	rest/=100;
	wHour=(WORD)(rest%100);
	rest/=100;
	wDay=(WORD)(rest%100);
	rest/=100;
	wMonth=(WORD)(rest%100);
	rest/=100;
	wYear=(WORD)(rest);

	return *this;
}

BOOL CMyTime::operator!=(const DATE &mt)
{
	CMyTime test;
	VariantTimeToSystemTime(mt,&test);

	return (*this!=test);
}

BOOL CMyTime::operator==(const CMyTime &mt)
{
	if(wMilliseconds != mt.wMilliseconds) return FALSE;
	if(wSecond != mt.wSecond) return FALSE;
	if(wMinute != mt.wMinute) return FALSE;
	if(wHour != mt.wHour) return FALSE;
	if(wDay != mt.wDay) return FALSE;
	if(wMonth != mt.wMonth) return FALSE;
	if(wYear != mt.wYear) return FALSE;
	return TRUE;
}

BOOL CMyTime::operator!=(const CMyTime &mt)
{
	if(wMilliseconds != mt.wMilliseconds) return TRUE;
	if(wSecond != mt.wSecond) return TRUE;
	if(wMinute != mt.wMinute) return TRUE;
	if(wHour != mt.wHour) return TRUE;
	if(wDay != mt.wDay) return TRUE;
	if(wMonth != mt.wMonth) return TRUE;
	if(wYear != mt.wYear) return TRUE;
	return FALSE;
}

BOOL CMyTime::operator>=(const CMyTime &mt)
{
	if(wYear > mt.wYear) return TRUE;
	else if(wYear < mt.wYear) return FALSE;
	
	if(wMonth > mt.wMonth) return TRUE;
	else if(wMonth < mt.wMonth) return FALSE;

	if(wDay > mt.wDay) return TRUE;
	else if(wDay < mt.wDay) return FALSE;

	if(wHour > mt.wHour) return TRUE;
	else if(wHour < mt.wHour) return FALSE;

	if(wMinute > mt.wMinute) return TRUE;
	else if(wMinute < mt.wMinute) return FALSE;

	if(wSecond > mt.wSecond) return TRUE;
	else if(wSecond < mt.wSecond) return FALSE;

	if(wMilliseconds > mt.wMilliseconds) return TRUE;
	else if(wMilliseconds < mt.wMilliseconds) return FALSE;

	return TRUE;
}

BOOL CMyTime::operator<=(const CMyTime &mt)
{
	if(wYear > mt.wYear) return FALSE;
	else if(wYear < mt.wYear) return TRUE;
	
	if(wMonth > mt.wMonth) return FALSE;
	else if(wMonth < mt.wMonth) return TRUE;

	if(wDay > mt.wDay) return FALSE;
	else if(wDay < mt.wDay) return TRUE;

	if(wHour > mt.wHour) return FALSE;
	else if(wHour < mt.wHour) return TRUE;

	if(wMinute > mt.wMinute) return FALSE;
	else if(wMinute < mt.wMinute) return TRUE;

	if(wSecond > mt.wSecond) return FALSE;
	else if(wSecond < mt.wSecond) return TRUE;

	if(wMilliseconds > mt.wMilliseconds) return FALSE;
	else if(wMilliseconds < mt.wMilliseconds) return TRUE;

	return TRUE;
}

BOOL CMyTime::operator>(const CMyTime &mt)
{
	if(wYear > mt.wYear) return TRUE;
	else if(wYear < mt.wYear) return FALSE;
	
	if(wMonth > mt.wMonth) return TRUE;
	else if(wMonth < mt.wMonth) return FALSE;

	if(wDay > mt.wDay) return TRUE;
	else if(wDay < mt.wDay) return FALSE;

	if(wHour > mt.wHour) return TRUE;
	else if(wHour < mt.wHour) return FALSE;

	if(wMinute > mt.wMinute) return TRUE;
	else if(wMinute < mt.wMinute) return FALSE;

	if(wSecond > mt.wSecond) return TRUE;
	else if(wSecond < mt.wSecond) return FALSE;

	if(wMilliseconds > mt.wMilliseconds) return TRUE;
	else if(wMilliseconds < mt.wMilliseconds) return FALSE;
							
	return FALSE;
}

BOOL CMyTime::operator<(const CMyTime &mt)
{
	if(wYear > mt.wYear) return FALSE;
	else if(wYear < mt.wYear) return TRUE;
	
	if(wMonth > mt.wMonth) return FALSE;
	else if(wMonth < mt.wMonth) return TRUE;

	if(wDay > mt.wDay) return FALSE;
	else if(wDay < mt.wDay) return TRUE;

	if(wHour > mt.wHour) return FALSE;
	else if(wHour < mt.wHour) return TRUE;

	if(wMinute > mt.wMinute) return FALSE;
	else if(wMinute < mt.wMinute) return TRUE;

	if(wSecond > mt.wSecond) return FALSE;
	else if(wSecond < mt.wSecond) return TRUE;

	if(wMilliseconds > mt.wMilliseconds) return FALSE;
	else if(wMilliseconds < mt.wMilliseconds) return TRUE;

	return FALSE;
}

int CMySTime::time_shift=0;

CMySTime::CMySTime()
{
	m_time=-1;
}

CMySTime::CMySTime(CMySTime &mt)
{
	m_time=mt.m_time;
}

CMySTime::CMySTime(DATE &date)
{
	SYSTEMTIME st;

	VariantTimeToSystemTime(date,&st);

	m_time=st.wHour*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;
}

void CMySTime::SetTime(WORD Hour, WORD Minute, WORD Second, WORD Millisecond)
{
	m_time=Hour*3600000+Minute*60000+Second*1000+Millisecond;
}

void CMySTime::ClearTime()
{
	m_time=-1;
}

//BYTE CMySTime::time_shift=0;

void CMySTime::SetCurrentTime()
{
	SYSTEMTIME st;
	FILETIME ft1;

	GetSystemTimeAsFileTime(&ft1);
	//FileTimeToLocalFileTime(&ft1,&ft1);
	FileTimeToSystemTime(&ft1,&st);

	if(time_shift>0)
	{
		if(st.wHour+time_shift<24) m_time=(st.wHour+time_shift)*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;
		else m_time=(st.wHour+time_shift-24)*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;
	}
	else if(time_shift<0)
	{
		if(st.wHour+time_shift>=0) m_time=(st.wHour+time_shift)*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;
		else m_time=(24+st.wHour+time_shift)*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;
	}
	else m_time=st.wHour*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;
}

void CMySTime::Shift()
{
	if(time_shift>0)
	{
		if((int)(m_time/3600000)+time_shift<24) m_time+=time_shift*3600000;
		else m_time+=(time_shift-24)*3600000;
	}
	else if(time_shift<0)
	{
		if((int)(m_time/3600000)+time_shift>=0) m_time+=time_shift*3600000;
		else m_time+=(24+time_shift)*3600000;
	}
}

int	CMySTime::GetHour()
{
	return (int)(m_time/3600000);
}

int	CMySTime::GetMin()
{
	return (int)((m_time%3600000)/60000);
}

int CMySTime::GetSec()
{
	return (int)((m_time%60000)/1000);
}

int CMySTime::GetMs()
{
	return m_time%1000;
}

int CMySTime::GetHourCount()
{
	return (int)(m_time/3600000);
}

int CMySTime::GetMinCount()
{
	return (int)(m_time/60000);
}

int CMySTime::GetSecCount()
{
	return (int)(m_time/1000);
}

int CMySTime::GetMsCount()
{
	return m_time;
}

void CMySTime::SetHour(int Hour)
{
	ASSERT(Hour>=0 && Hour<=23);

	m_time=Hour*3600000+(int)((m_time%3600000)/60000)*60000+(int)((m_time%60000)/1000)*1000+m_time%1000;
}

void CMySTime::SetMin(int Min)
{
	ASSERT(Min>=0 && Min<=59);

	m_time=(int)(m_time/3600000)*3600000+Min*60000+(int)((m_time%60000)/1000)*1000+m_time%1000;
}

void CMySTime::SetSec(int Sec)
{
	ASSERT(Sec>=0 && Sec<=59);

	m_time=(int)(m_time/3600000)*3600000+(int)((m_time%3600000)/60000)*60000+Sec*1000+m_time%1000;
}

void CMySTime::SetMs(int Ms)
{
	ASSERT(Ms>=0 && Ms<=999);

	m_time=(int)(m_time/1000)*1000+Ms;
}

CString CMySTime::GetShortTime()
{
	CString str;
	int m_time_cpy=m_time; // making a copy to be sure that value not changed

	if(m_time_cpy!=-1) str.Format("%02u:%02u:%02u", (int)(m_time_cpy/3600000), (int)((m_time_cpy%3600000)/60000), (int)((m_time_cpy%60000)/1000));
	else str="-";

	return str;
}

CString CMySTime::GetShortTimeEx()
{
	CString str;
	int m_time_cpy=m_time; // making a copy to be sure that value not changed

	if(m_time_cpy!=-1) str.Format("%02u:%02u:%02u.%03u", (int)(m_time_cpy/3600000), (int)((m_time_cpy%3600000)/60000), (int)((m_time_cpy%60000)/1000), m_time_cpy%1000);
	else str="-";

	return str;
}

BOOL CMySTime::IsCorrect()
{
	if(m_time<0 || m_time>172800000) return FALSE;
	else return TRUE;
}

BOOL CMySTime::IsNull()
{
	if(m_time==-1) return TRUE;
	else return FALSE;
}

void CMySTime::InitTimeShift()
{
	FILETIME ft1, ft2;
	SYSTEMTIME st1, st2;

	GetSystemTimeAsFileTime(&ft1);
	FileTimeToLocalFileTime(&ft1,&ft2);
	FileTimeToSystemTime(&ft1,&st1);
	FileTimeToSystemTime(&ft2,&st2);

	if(st1.wDay==st2.wDay) CMySTime::time_shift=st2.wHour-st1.wHour;
	else if(st2.wDay>st1.wDay) CMySTime::time_shift=st2.wHour+24-st1.wHour;
	else CMySTime::time_shift=(st1.wHour+24-st2.wHour)*-1;
}

// returns difference between two dates as count of milliseconds
int CMySTime::operator-(const CMySTime &mt)
{
	return m_time-mt.m_time;
}

// returns difference between two dates as count of seconds
int CMySTime::GetDiffSec(CMySTime &mt)
{
	return (int)((m_time-mt.m_time)/1000);
}

void CMySTime::operator-=(const int shift_ms)
{
	m_time-=shift_ms;
}

void CMySTime::operator+=(const int shift_ms)
{
	m_time+=shift_ms;
}

CMySTime& CMySTime::operator=(const DATE &mt)
{
	SYSTEMTIME st;

	VariantTimeToSystemTime(mt,&st);

	m_time=st.wHour*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;

	return *this;
}

void CMySTime::SetFromTimeT32(const long &mt)
{
	m_time=(mt%86400)*1000;
}

void CMySTime::SetFromTimeT64(const __int64 &mt)
{
	m_time=(mt%86400)*1000;
}

CMySTime& CMySTime::operator=(const CTime &mt)
{
	SYSTEMTIME st;

	mt.GetAsSystemTime(st);

	m_time=st.wHour*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;

	return *this;
}

CMySTime& CMySTime::operator=(const ULONGLONG &mt)
{
	ULONGLONG rest=mt;

	m_time=(int)(rest%1000);
	rest/=1000;
	m_time+=(int)(rest%100)*1000;
	rest/=100;
	m_time+=(int)(rest%100)*60000;
	rest/=100;
	m_time+=(int)(rest%100)*3600000;

	return *this;
}

CMySTime& CMySTime::operator=(const CMyTime &mt)
{
	m_time=mt.wHour*3600000+mt.wMinute*60000+mt.wSecond*1000+mt.wMilliseconds;

	return *this;
}

CMySTime& CMySTime::operator=(const int &mt)
{
	m_time=mt;

	return *this;
}

BOOL CMySTime::operator!=(const DATE &mt)
{
	long test;
	SYSTEMTIME st;

	VariantTimeToSystemTime(mt,&st);

	test=st.wHour*3600000+st.wMinute*60000+st.wSecond*1000+st.wMilliseconds;

	return (m_time!=test);
}

BOOL CMySTime::operator==(const CMySTime &mt)
{
	if(m_time == mt.m_time) return TRUE;
	else return FALSE;
}

BOOL CMySTime::operator!=(const CMySTime &mt)
{
	if(m_time != mt.m_time) return TRUE;
	else return FALSE;
}

BOOL CMySTime::operator>=(const CMySTime &mt)
{
	if(m_time >= mt.m_time) return TRUE;
	else return FALSE;
}

BOOL CMySTime::operator<=(const CMySTime &mt)
{
	if(m_time <= mt.m_time) return TRUE;
	else return FALSE;
}

BOOL CMySTime::operator>(const CMySTime &mt)
{
	if(m_time > mt.m_time) return TRUE;
	else return FALSE;
}

BOOL CMySTime::operator<(const CMySTime &mt)
{
	if(m_time < mt.m_time) return TRUE;
	else return FALSE;
}
